#ifndef TIMESEQUENCE_HPP
#define TIMESEQUENCE_HPP
#include <vector>
#include <algorithm>

namespace TermStructure{
    //! Time Sequence. The times that all the data are based on.
    /*! Most of times, all classes will maintain a poitner to the same copy of a TimeSequence. It should be seldomly changed after initialization.
     The first in the time sequence will always be zero, and will be automatically pushed into the sequence when it is created.
     So don't push zero into the time sequence.
     */
	template<typename T,typename TSize=long>
	class TimeSequence
	{
        //! Times
		std::vector<T> _times;
        //! The Time Intervals
        std::vector<T> _timeDifferences;
	public:
        //! Default Constructor
		TimeSequence()
		{
			_times.push_back(0);
            _timeDifferences.push_back(0);
		}
        //! Copy constructure
		TimeSequence(const TimeSequence &anotherTimeSequence)
		{
			this->_times.insert(this->_times.begin(), anotherTimeSequence._times.begin(), anotherTimeSequence._times.end());
            this->_timeDifferences.inser(this->_timeDifferences.begin(), anotherTimeSequence._timeDifferences.begin(), anotherTimeSequence._timeDifferences.end());
		}
        //! operator =
		TimeSequence &operator=(const TimeSequence &anotherTimeSequence)
		{
			if(this != &anotherTimeSequence)
			{
				this->_times.clear();
				this->_times.insert(this->_times.begin(), anotherTimeSequence._times.begin(), anotherTimeSequence._times.end());
                this->_timeDifferences.clear();
                this->_timeDifferences.inser(this->_timeDifferences.begin(), anotherTimeSequence._timeDifferences.begin(), anotherTimeSequence._timeDifferences.end());
			}
		}
        //! Add another time to the sequence
		TimeSequence& PutTime(const T &time)
		{
            _timeDifferences.push_back(time - _times.back());
			_times.push_back(time);
			return *this;
		}
        //! Get the time difference/interval which is T_{i-1}-T_i
		T TimeDifference(TSize i ) const
		{
			return _timeDifferences[i];
		}
        //! Get the time
		T GetTime(TSize i) const
		{
			return _times[i];
		}
        //! GEt the size of the time sequence
		TSize GetSize() const
		{
			return _times.size();
		}
        //! Get the index of the time sequence
		TSize GetIndex(T t)
		{
			 TSize index = std::find(_times.begin(), _times.end(), t) - _times.begin();
			 return index;	
		}
	};
}

#endif